package com.designpattern.design.visitor;

import java.util.ArrayList;
import java.util.List;

/**
 * 访问者模式
 * @author 15790
 *
 */
public class VisitorTest {
public static void main(String[] args) {
	ObjectStructor structor = new ObjectStructor();
	//定义三个人做评价
	structor.attach(new Man());
	structor.attach(new Man());
	structor.attach(new Woman());
	//第一次评价 成功
	 Success success = new Success();
	 structor.display(success);
	 //第二次评价 失败
	 Fail fail = new Fail();
	 structor.display(fail);
	 /**
	  * 这样设计的好处是 后续扩展成功失败 都不影响评价对象
	  * 实现了对象的多次评价
	  */
	 
}
}

/**
 * 抽象被访问对象
 * @author 15790
 *
 */
abstract class Person{
	//提供访问方法，让访问者能够访问
	 public abstract void accept(Action action);
}
/**
 * 具体被访问对象
 * @author 15790
 *这里我们使用到了双分派 首先是在客户端按照类型分派给男人女人
 *然后男人女人将自己作为参数分派到具体实现的类型当中得到具体结果
 */
class Man extends Person{

	@Override
	public void accept(Action action) {
		// TODO Auto-generated method stub
		/**
		 * 男人只能获取男人的评价 所以把自己传进去就可以了
		 */
		action.getManResult(this);
	}
	
}
/**
 * 具体被访问对象
 * @author 15790
 *
 */
class Woman extends Person{

	@Override
	public void accept(Action action) {
		// TODO Auto-generated method stub
		/**
		 * 女人只能获取女人的评价 所以把自己传进去就可以了
		 */
		action.getWomanResult(this);
	}
	
}

/**
 * 抽象访问者
 * @author 15790
 *
 */
abstract class Action{
	public abstract void getManResult(Man man);
	public abstract void getWomanResult(Woman woman);
}
/**
 * 具体访问者
 * @author 15790
 *
 */
class Success extends Action{

	@Override
	public void getManResult(Man man) {
		// TODO Auto-generated method stub
		System.out.println("当前男人对评价是成功");
	}

	@Override
	public void getWomanResult(Woman woman) {
		// TODO Auto-generated method stub
		System.out.println("当前女人对评价是成功");	
	}
	
}
class Fail extends Action{

	@Override
	public void getManResult(Man man) {
		// TODO Auto-generated method stub
		System.out.println("当前男人对评价是失败");
	}

	@Override
	public void getWomanResult(Woman woman) {
		// TODO Auto-generated method stub
		System.out.println("当前女人对评价是失败");	
	}
	
}
/**
 * 对象构建类-用以管理多人评价
 * @author 15790
 *
 */
class ObjectStructor{
	List<Person> persons=new ArrayList<>();
	
	public void attach(Person person) {
		persons.add(person);
	}
	public void remove(Person person) {
		persons.remove(person);
	}
	/**
	 * 显示测评状况
	 */
	public void display(Action action) {
		for(Person person:persons) {
			person.accept(action);
		}
	}
}